/*Shift-JIS*/
/*UTF-8*/
#include "../coredef.h"
#include "cc.h"

static	S4	gblExitCode ;
#define IS_ILLEGAL_SIZE( s4_Num ) (( s4_Num <= 0 ) || ( s4_Num != 1 && s4_Num != 2 && s4_Num%4 != 0 ))

static  struct _VALID_PTRDIFF_TYPE
{
	PSZ typename;
	AST  typeidx;
}stValidPtrDiffType[]=
{
		{ "short", TYPE_SHORT },
		{ "int",   TYPE_INT },
		{ "long", TYPE_LONG },
		{ "longlong", TYPE_LONG_LONG },
		{ NULL, 0 }
};


static  struct _VALID_SIZEOF_TYPE
{
	PSZ typename;
	AST  typeidx;
}stValidSizeofType[]=
{
		{ "short", TYPE_SHORT},
		{ "unsigned_short",   TYPE_UNSIGNED_SHORT },
		{ "int", TYPE_INT },
		{ "unsigned_int", TYPE_UNSIGNED_INT },
		{ "long", TYPE_LONG},
		{ "unsigned_long", TYPE_UNSIGNED_LONG },
		{ "longlong", TYPE_LONG_LONG },
		{ "unsigned_longlong", TYPE_UNSIGNED_LONG_LONG },
		{ NULL, 0 }
};
static  struct _VALID_ENUM_TYPE
{
	PSZ typename;
	AST  typeidx;
	AST  typebegin;
}stValidEnumType[]=
{
		{ "adjustable", 0, TYPE_INT },
		{ "shortenum", 0, TYPE_CHAR },
		{ "char", TYPE_CHAR, TYPE_CHAR},
		{ "signed_char", TYPE_SIGNED_CHAR, TYPE_SIGNED_CHAR },
		{ "unsigned_char", TYPE_UNSIGNED_CHAR, TYPE_UNSIGNED_CHAR },
		{ "short", TYPE_SHORT, TYPE_SHORT},
		{ "unsigned_short",   TYPE_UNSIGNED_SHORT,   TYPE_UNSIGNED_SHORT },
		{ "int", TYPE_INT, TYPE_INT },
		{ "unsigned_int", TYPE_UNSIGNED_INT, TYPE_UNSIGNED_INT  },
		{ "long", TYPE_LONG, TYPE_LONG},
		{ "unsigned_long", TYPE_UNSIGNED_LONG, TYPE_UNSIGNED_LONG },
		{ NULL, 0, 0 }
};
static VOID ccOpenMem()
{
	stCcLabelStrAccess.clear();
	stBlockNestAccess.clear();
	stCCDefSymChainAccess.clear();
	stCCLoopSwitchStackAccess.clear();
	stObjectMapOfTypeAccess.clear();
	stDeclarationAccess.clear();
	stDeclaratorAccess.clear();
	stExpressionAccess.clear();
	stExpressionListAccess.clear();
	stInitDesignationAccess.clear();
	stLexTokenAccess.clear();
	stCCLinkageAccess.clear();
	stStatementAccess.clear();
	stSymbolInfoAccess.clear();
	stTypeCmpStkAccess.clear();
	stTypeSpecifierAccess.clear();
	stTypeCmpStkAccess.clear();
	stTypeInfoAccess.clear();
	stUniteChainAccess.clear();
	stValueInfoAccess.clear();
}
/**************************************************************
 * 1. 関数名	ccCloseMem
 * 2. 引数      無し
 * 3. 戻り値
 *          EXIT_SUCCESS		正常終了
 *          EXIT_FATAL			致命エラー
**************************************************************/
static VOID ccCloseMem()
{
	stCcLabelStrAccess.clear();
	stBlockNestAccess.clear();
	stCCDefSymChainAccess.clear();
	stCCLoopSwitchStackAccess.clear();
	stObjectMapOfTypeAccess.clear();
//	stDeclarationAccess.clear();
//	stDeclaratorAccess.clear();
//	stExpressionAccess.clear();
//	stExpressionListAccess.clear();
//	stInitDesignationAccess.clear();
	stLexTokenAccess.clear();
//	stCCLinkageAccess.clear();
//	stStatementAccess.clear();
//	stSymbolInfoAccess.clear();
	stTypeCmpStkAccess.clear();
//	stTypeSpecifierAccess.clear();
	stTypeCmpStkAccess.clear();
//	stTypeInfoAccess.clear();
//	stUniteChainAccess.clear();
//	stValueInfoAccess.clear();
}

/******************************************************************
* 関 数 名 : cppProcOption
* 機    能 :
* 引    数 : VOID
* 戻 り 値 : S4
* 	　　　:１．　正常終了時：	COEXIT_SUCCESS
* 　　　　　 ：２．　致命エラー：	COEXIT_FATAL
* 	   :3.  エラー終了         COEXIT_ERROR
* 詳細内容 :
*******************************************************************/
static S4 ccProcOption( VOID )
{
	/*　初期値設定　*/
	AST astCnt;
	AST astMax = stCoreOptAccess.getMax();
	U2 optId;
	S4 nRet, result = COEXIT_SUCCESS, i=0;
	PSZ pszOptStr;
	for( astCnt = MIN_ARRAY; astCnt <= astMax; astCnt ++ )
	{
		optId = stCoreOptAccess.optId.get(astCnt);
		pszOptStr = stCoreOptAccess.strValue.get( astCnt );
		switch( optId )
		{
		case	OPTID_CMPLKIND	:
			nRet = MpuProcOption( pszOptStr );
			if( nRet != COEXIT_SUCCESS )
			{
				result = nRet > result?nRet:result;
			}
			break;
		case	OPTID_PTRDIFF_TYPE	:
			pszOptStr =stCoreOptAccess.strValue.get(astCnt) ;
			for(i = 0; stValidPtrDiffType[i].typename != NULL; i++ ){
				if( strcmp( stValidPtrDiffType[i].typename, pszOptStr ) == 0 ){
					stCoreEnvInfo.astDiffPtrType = stValidPtrDiffType[i].typeidx;
					break;
				}
			}
			if( stValidPtrDiffType[i].typename == NULL ){
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
			}
			break;
		case	OPTID_SIZEOF_TYPE	:
			for(i = 0; stValidSizeofType[i].typename != NULL; i++ )
			{
				if( strcmp( stValidSizeofType[i].typename, pszOptStr ) == 0 )
				{
					stCoreEnvInfo.astSizeofType = stValidSizeofType[i].typeidx;
					break;
				}
			}
			if( stValidSizeofType[i].typename == NULL )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;

			}
			break;
		case	OPTID_ENUMTYPE	:
			for(i = 0; stValidEnumType[i].typename != NULL; i++ )
			{
				if( strcmp( stValidEnumType[i].typename, pszOptStr ) == 0 )
				{
					stCoreEnvInfo.astEnumType = stValidEnumType[i].typeidx;
					stCoreEnvInfo.astEnumBegin = stValidEnumType[i].typebegin;/*shortenum 対応    */
					break;
				}
			}
			if( stValidEnumType[i].typename == NULL )
			{
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
			}
			break;
		case	OPTID_CHAR_UNSIGNED	:
			stCoreEnvInfo.ucCharSign = OPT_CHAR_UNSIGNED;
			break;
		case	OPTID_BIT_UNSIGNED	:
			stCoreEnvInfo.ucBitSign = OPT_BIT_UNSIGNED;
			break;
		case	OPTID_BIT_SIGNED	:
			stCoreEnvInfo.ucBitSign = OPT_BIT_SIGNED;
			break;
		case	OPTID_NEARFAR	:
			stCoreEnvInfo.ucNearFar = TRUE;
			break;
		case OPTID_SHIFT_BITNUM_REMAINDER:
			stCoreEnvInfo.ucShiftWhenOverflow = OPT_SHIFT_BITNUM_REMAINDER;
			break;
		case OPTID_SHIFT_BITNUM_ALL:
			stCoreEnvInfo.ucShiftWhenOverflow = OPT_SHIFT_BITNUM_ALL;
			break;
		case OPTID_SHIFT_KIND_ARITH:
			stCoreEnvInfo.ucShiftKind = OPT_SHIFT_ARITH;
			break;
		case OPTID_SHIFT_KIND_LOGICAL:
			stCoreEnvInfo.ucShiftKind = OPT_SHIFT_LOGICAL;
			break;
		case OPTID_MODULO_SIGNED:
			stCoreEnvInfo.ucModuloSign = OPT_MODULO_SIGNED;
			break;
		case OPTID_MODULO_UNSIGNED:
			stCoreEnvInfo.ucModuloSign = OPT_MODULO_UNSIGNED;
			break;
		case OPTID_BREAK_PPNUM:
			stCoreEnvInfo.ucBreakPPNum = TRUE;
			break;
		case	OPTID_BIT_TYPE	:
			stCoreEnvInfo.ucBitType = TRUE;
			break;
		case	OPTID_CPPCOMMENT	:
			break;
		case	OPTID_CPPRESULT	:
			break;
		case	OPTID_SRC_MACRO	:
			break;
		case	OPTID_FUNCTION_MACRO	:
			break;
		case	OPTID_MAX_ALIGNMENT	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );

				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
			}
			stCoreEnvInfo.ucMaxAlignment = s4_Num;
			break;
		}
		case OPTID_BITBYTE_NEW:
			stCoreEnvInfo.ucBitByte_new_align= TRUE;
			break;
		case OPTID_BYTEBIT_NEW:
			stCoreEnvInfo.ucByteBit_new_align= TRUE;
			break;
		case OPTID_BITBIT_BYSIZE:
			stCoreEnvInfo.ucBitBit_size_alignment= TRUE;
			break;
		case OPTID_DIVIDE_BIT:
			stCoreEnvInfo.ucBit_divide= TRUE;
			break;
		case OPTID_ZEROBIT:
			stCoreEnvInfo.ucBit_zero_self= TRUE;
			break;
		case OPTID_BITBIT_ARRAGNE:
			stCoreEnvInfo.ucBitBit_arrange_bysize = TRUE;
			break;
		case	OPTID_POINTERSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			POINTERSIZE = s4_Num;
			break;
		}
		case	OPTID_NEAR_POINTERSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			NEARPOINTERSIZE = s4_Num;
			break;
		}
		case	OPTID_FAR_POINTERSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			FARPOINTERSIZE = s4_Num;
			break;
		}
		case	OPTID_SHORTSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			SHORTSIZE = s4_Num;
			break;
		}
		case	OPTID_INTSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			INTSIZE = s4_Num;
			break;
		}
		case	OPTID_LONGSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			LONGSIZE = s4_Num;
			break;
		}
		case	OPTID_FLOATSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			FLOATSIZE = s4_Num;
			break;
		}
		case	OPTID_DBLSZIE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			DOUBLESIZE = s4_Num;
			break;
		}
		case	OPTID_LONGDBLSIZE	:
		{
			S4 s4_Num = strtol( pszOptStr, &pszOptStr, 10 );
			if(  IS_ILLEGAL_SIZE(s4_Num) )
			{
				ALERT_MSG_PARAM temp;
				temp.opt = CCoreGetOptKey( optId );
				temp.param = pszOptStr;
				temp.next = 0;
				CcThrowWarning( CPP_OPT_ILLEGAL_PARAM, 0, CCoreGetOptKey( optId ), &temp );
				result = COEXIT_ERROR > result?COEXIT_ERROR:result;
				break;
			}
			LONGDOUBLESIZE = s4_Num;
			break;
		}
		case	OPTID_BUILDINFUNC	:
			break;
		case	OPTID_I_SYM	:
		case	OPTID_I_USER	:
		case	OPTID_DMACRO	:
		case	OPTID_UMACRO	:
		case	OPTID_NMACRO	:
			break;
		case    OPTID_C90:
			stCoreEnvInfo.ucC90 = TRUE;
			stCoreEnvInfo.ucC99 = FALSE;
			stCoreEnvInfo.ucGNU = FALSE;
			break;
		case    OPTID_C99:
			stCoreEnvInfo.ucC90 = FALSE;
			stCoreEnvInfo.ucC99 = TRUE;
			stCoreEnvInfo.ucGNU = FALSE;
			break;
		case    OPTID_GNU:
			stCoreEnvInfo.ucC90 = FALSE;
			stCoreEnvInfo.ucC99 = FALSE;
			stCoreEnvInfo.ucGNU = TRUE;
			break;
		default:
			result = COEXIT_ERROR;
			break;
		}
	}
	return result;
}
/***************************************************************
 * 1. 関数名		CSyntaxProcessing
 * 2. 原型		S4 CSyntaxProcessing ( void )
 * 3. 引数             VOID
 * ４ .戻り値		EXIT_SUCCESS		正常終了
 * 				EXIT_SUCCESS		正常終了
 * 				EXIT_WARNING		警告
 * 				EXIT_ERROR			コンパイルエラー
 * 				EXIT_FATAL			致命エラー
 * 5. 履歴		20090903　陳改訂済み　：　改訂番号　--- 1
 **************************************************************/
S4 DLL_EXPORT CSyntaxProcessing ( VOID )
{
	AST astTempDec ;
	AST astTu = CCoreGetCurrTranslatioUnit();
    gblExitCode = COEXIT_SUCCESS ;
    TRY;
    ccOpenMem() ;
    CcLexInit( astTu ) ;
    CcTypeInitial();
    CcSymInitial();
    CcBlockInitial();
    CcStmtInit() ;
    CcDeclInit() ;
    CcValueInit();
    gblExitCode = ccProcOption();
    if( gblExitCode == COEXIT_SUCCESS ){
		astTempDec = CcDeclarationList();
		stCoreTranslationUnitAccess.declarationchain.set(astTu, astTempDec);
    }

    ccCloseMem() ;
    CATCH(COEXIT_FATAL);
    return gblExitCode ;
}
VOID DLL_EXPORT ClearTUSyntaxProcessingResult( VOID ){
	stCcLabelStrAccess.clear();
	stBlockNestAccess.clear();
	stCCDefSymChainAccess.clear();
	stCCLoopSwitchStackAccess.clear();
	stObjectMapOfTypeAccess.clear();
	stDeclarationAccess.clear();
	stDeclaratorAccess.clear();
	stExpressionAccess.clear();
	stExpressionListAccess.clear();
	stInitDesignationAccess.clear();
	stLexTokenAccess.clear();
	stCCLinkageAccess.clear();
	stStatementAccess.clear();
	stSymbolInfoAccess.clear();
	stTypeCmpStkAccess.clear();
	stTypeSpecifierAccess.clear();
	stTypeCmpStkAccess.clear();
	stTypeInfoAccess.clear();
	stUniteChainAccess.clear();
	stValueInfoAccess.clear();
}
VOID  CcThrowWarning( U4 code, AST astCodeScp, PSZ pszParameter, ALERT_MSG_PARAM *szValue ){
	S4 errcode = CCoreThrowWarning( code, astCodeScp, pszParameter, szValue );
	gblExitCode = errcode > gblExitCode? errcode : gblExitCode;
}
/* end of file */
